do

Network = {}


-- 回调
-- 客户端每发一个请求都会注册一个回调，回调的唯一的，并且仅触发一次。一般做法是生成一个唯一key来进行回调映射并且作为发送的packet.id值，服务器会在返回的packet中透传回客户端
local callbacks = {}

-- 监听器
-- 监听器的主要作用是，监听服务器主动推送的消息监听。便于我们处理代码业务
local listeners = {}


-- 解码器：
-- 之所有此处还需要一次解码，是因为在网络传输过程中所有的消息key是转为了hashcode进行传输，
-- 占用字节更少，所以需要把hashcode转回我们代码中使用的字符key。节约宽带提高传输效率
-- 如果是不传数字key时，可以删除解码器
decoders = {}

-- 结构体
structs = {}


-- 判断是否是数组
isArray = function(t)
    if t == nil then
        return false, 0;
    end
    local i = 0
    local ret = true;
    for _ in pairs(t) do
        i = i + 1
        if t[i] == nil then
            ret = false
        end
    end
    return ret, i
end

objectDecode = function(o)
    local isTable = type(o)
    if isTable == "table" then
        local isArray, len = isArray(o)
        if isArray then
            return listDecode(o)
        else
            local struct = structs[o[183928832]]
            if struct then
                return struct.decode(o)
            else
                return mapDecode(o)
            end
        end
    else
        return o;
    end
end

-- 解析List
listDecode = function(o)
    local ret = {};
    for i, v in pairs(o) do
        table.insert(ret, objectDecode(v))
    end
    return ret
end

mapDecode = function(map)
    local ret = {};
    for key, value in pairs(map) do
        ret[objectDecode(key)] = objectDecode(value)
    end
    return ret;
end



objectEncode = function(o)
    local isTable = type(o)
    if isTable == "table" then
        local isArray, len = isArray(o)
        if isArray then
            return listEncode(o)
        else
            local struct = structs[o[183928832]]
            if struct then
                local r = struct.encode(o)
                r[183928832] = o[183928832];
                return r;
            else
                return mapEncode(o)
            end
        end
    else
        return o;
    end
end

-- 解析List
listEncode = function(o)
    local ret = {};
    for i, v in pairs(o) do
        table.insert(ret, objectEncode(v))
    end
    return ret
end

mapEncode = function(map)
    local ret = {};
    for key, value in pairs(map) do
        ret[objectEncode(key)] = objectEncode(value)
    end
    return ret;
end

-- 注册回调(回调函数,上下文)
local registerCallback = function (callback, context)
   if callback then
       callbacks[callbackKey] = {callback, context}
    end
end

-- 注册监听器(监听处理函数)
local registerListener = function (callback)
   if callback then
       listeners[callbackKey] = {callback}
    end
end


-- 分发器、接收服务器消息的唯一入口，便于处理错误码等情况
Network.disp = function(packet)
	-- 回调
	local callback = callbacks[callbacks.Id];
	-- 监听
	local listener = listeners[callbacks.CommandId];

	if packet.status ~= 0 then
		-- 错误码提示:

	else
		-- 消息解码
		local result = Network.decoder[callbacks.CommandId](packet.Body)

		-- 执行回调
		if callback then
			pcall(callback[1], callback[2], result)
		end

		-- 执行监听
		if listener then
			pcall(listener[1], result)
		end
	end

	-- 移除回调
	if callback then
		callbacks[callbacks.Id] = nil
	end

end

-- 发送消息模块，类似RPC调用，调用者不必关心内部实现
Network.module = {
    Player = {
        -- 请求
        -- 进入游戏
        enterGame = function(loginServerId,token,callback,context)

            -- 1.包封装
            local packet = {
                -- Head
                [1] = {
                    [1] = os.time(),
                    [2] = 450960106
                },
                -- Body
                [2] = {
                    [451300935] = objectEncode(loginServerId);
                    [110541305] = objectEncode(token);
                }
            }

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,


        -- 推送
        -- 推送
        notifyPlayer = 450970506;
    },
}

-- *************** 解码器 ***************

-- 进入游戏
decoders[450960106] = function(body)
    local o = {}
    o.index = objectDecode(body[100346066]);
    o.player = objectDecode(body[-985752863]);
    return o;
end

-- 推送
decoders[450970506] = function(body)
    local o = {}
    o.loginServerId = objectDecode(body[451300935]);
    o.token = objectDecode(body[110541305]);
    return o;
end





-- *************** 结构体 ***************

-- 玩家简单信息
PlayerInfoDTO = {
    encode = function(o)
        local r = {};
        r[115792] = objectEncode(o.uid);    -- 用户ID
        r[110987] = objectEncode(o.pid);    -- 玩家ID
        r[3373707] = objectEncode(o.name);    -- 昵称
        r[107554] = objectEncode(o.lvl);    -- 等级
        r[100893] = objectEncode(o.exp);    -- 经验
        r[3226745] = objectEncode(o.icon);    -- 头像
        r[3575610] = objectEncode(o.type);    -- 类型
        return r
    end,
    decode = function(o)
        local r = {};
        r.uid = objectDecode(o[115792]);    -- 用户ID
        r.pid = objectDecode(o[110987]);    -- 玩家ID
        r.name = objectDecode(o[3373707]);    -- 昵称
        r.lvl = objectDecode(o[107554]);    -- 等级
        r.exp = objectDecode(o[100893]);    -- 经验
        r.icon = objectDecode(o[3226745]);    -- 头像
        r.type = objectDecode(o[3575610]);    -- 类型
        return r
    end,
    new = function()
        return {[183928832] = 1102355472};
    end
}

-- 玩家信息
PlayerDTO = {
    encode = function(o)
        local r = {};
        r[2095520559] = objectEncode(o.playerInfo);    -- 基本信息
        return r
    end,
    decode = function(o)
        local r = {};
        r.playerInfo = objectDecode(o[2095520559]);    -- 基本信息
        return r
    end,
    new = function()
        return {[183928832] = 131897118};
    end
}






structs[1102355472] = PlayerInfoDTO
structs[131897118] = PlayerDTO

end
